
const TIANDI_KEY = "0416fde74c65c0b7f8603ff0fbcc71c7";
const layerTypeMap = {
    SL: ["vec", "cva"], // [矢量底图, 矢量注记]
    YX: ["img", "cia"], // [影像底图, 影像注记]
    DX: ["ter", "cta"], // [地形晕渲, 地形注记]
};
const layerType = "SL";
const matrixSet = "c"; //c：经纬度投影w:球面投影
import Map from "ol/Map.js";
import { Style, Fill, Text, Stroke, Image, Icon, IconImage } from "ol/style";
import TileLayer from "ol/layer/Tile.js";
import Overlay from 'ol/Overlay.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import VectorLayer from 'ol/layer/Vector.js';
import { Cluster, Vector as VectorSource } from 'ol/source.js';
import View from "ol/View.js";
import WMTS from "ol/source/WMTS.js";
import WMTSTileGrid from "ol/tilegrid/WMTS.js";
import { get as getProjection, fromLonLat } from "ol/proj.js";
import { getTopLeft, getWidth } from "ol/extent.js";
import MousePosition from 'ol/control/MousePosition.js';
import { createStringXY } from 'ol/coordinate.js';
import { defaults as defaultControls } from 'ol/control.js';
const mousePositionControl = new MousePosition({
    coordinateFormat: createStringXY(6),
    projection: 'EPSG:4326',
    className: 'custom-mouse-position',
    target: document.getElementById('mouse-position'),
});

const projection = getProjection("EPSG:4326");
const projectionExtent = projection.getExtent();
const size = getWidth(projectionExtent) / 256;
const resolutions = new Array(19);
const matrixIds = new Array(19);
for (let z = 0; z < 19; ++z) {
    resolutions[z] = size / Math.pow(2, z);
    matrixIds[z] = z;
}
const isMapReady = ref(false)
/** @type {import('./useMap.d.ts').Map} 地图实例对象  */
export const map = shallowRef(null)
export const titleLayer = shallowRef(null)
/** @type {object} 地图view实例对象shallowRef  */
export const view = shallowRef(new View({
    projection: "EPSG:4326",
    center: [0, 0],
    zoom: 10,
    maxZoom: 18,
}))
export const getMap = () => {
    return map
}
/** @type {import('./useMap.d.ts').useAnimateTo}  */
export const useAnimateTo = ({ center, zoom = 11, duration = 1000 }, fn) => {
    view.value && view.value.animate({
        zoom, center, duration
    });
    setTimeout(() => {
        fn()
    }, duration);
}
/** @type {import('./useMap.d.ts').initTdLayer}  */
export const initTdLayer = (map, layerType = 'vec', matrixSet = 'c') => {
    const viewer = toValue(map)
    const layer = new TileLayer({
        source: new WMTS({
            name: "矢量底图",
            url: `http://t{0-7}.tianditu.gov.cn/${layerType}_${matrixSet}/wmts?tk=${TIANDI_KEY}`,
            layer: layerType,
            matrixSet: matrixSet,
            style: "default",
            format: "tiles",
            wrapX: true,
            tileGrid: new WMTSTileGrid({
                origin: getTopLeft(projectionExtent),
                resolutions,
                matrixIds,
            }),
        })
    })
    viewer && viewer.addLayer(layer)
    return layer
}
export const addVectorLayer = (map, features, icon = 'plan') => {
    const viewer = toValue(map)
    const geofeatures = new GeoJSON().readFeatures(features)
    const source = new VectorSource({
        features: geofeatures,
    });
    const clusterSource = new Cluster({
        distance: 40,
        minDistance: 25,
        source: source,
    });
    const layer = new VectorLayer({
        source: clusterSource,
        style: function (feature) {
            const isOnlyFeature = feature.values_.features.length === 1;
            const featureLen = feature.values_.features.length
            const text = isOnlyFeature ? feature.values_.features[0].values_.picName : String(featureLen)
            return new Style({
                text: new Text({
                    text,
                    offsetY: isOnlyFeature ? 20 : 0,
                    font: '14px',
                    fill: new Fill({
                        color: isOnlyFeature ? "#10e" : "#fff",
                    })
                }),
                image: new Icon({
                    src: isOnlyFeature ? `/${icon}.png` : `/${icon}-jh.png`, // 图片的URL
                    width: 40,
                    height: 40
                })
            })
        },
        zIndex: 999
    });
    viewer && viewer.addLayer(layer)
    return layer
}
export const useMapClick = () => {
    const currentFeatures = shallowReactive({
        type: 1,
        coordinate: [],
        features: []
    })
    watch(map, (viewer, oldValue) => {
        if (viewer) {
            viewer.on('click', (e) => {
                console.log(e);
                const features = viewer.getFeaturesAtPixel(e.pixel)
                const isOnlyFeature = features[0].values_.features.length === 1
                if (isOnlyFeature) {
                    currentFeatures.type = 1

                } else {
                    currentFeatures.type = 2
                }
                currentFeatures.coordinate = e.coordinate
                currentFeatures.features = features[0].values_.features
            });
        }
    })
    const destory = () => {
        map.value && map.value.un('click', () => {
            console.log('卸载监听点击事件');
        })
    }
    const click = () => {

    }
    return { features: currentFeatures, destory, click }
}
export const useOverlay = (map, element) => {
    let layer = null;
    const vnodeApp = {
        value: null
    }
    const nodeContainer = document.createElement(`div`)
    nodeContainer.id = 'zd-overlay'
    const bodyDom = document.body
    bodyDom.appendChild(nodeContainer)
    const close = () => {
        layer.setPosition(undefined);
    }
    const open = (coordinate) => {
        const dom = vnodeApp.value._container.children[0]
        layer.setElement(dom)
        layer.setPosition(coordinate)
    }
    const create = (el, attrs) => {
        vnodeApp.value && vnodeApp.value.unmount()
        vnodeApp.value = createApp(h(el, attrs))
        vnodeApp.value.mount('#zd-overlay')
    }
    const destory = () => {
        map.value.removeOverlay(layer)
    }
    watch(isMapReady, (newValue, oldValue) => {
        const viewer = toValue(map)
        layer = new Overlay({
            autoPan: {
                animation: {
                    duration: 250,
                },
            },
        });
        if (element && element.value) {
            layer.setElement(toValue(element))
        }
        viewer && viewer.addOverlay(layer)
    })
    return { open, close, create, destory }
}
/** @type {import('./useMap.d.ts').useMap}  */
export const useMap = (el = 'map', center = [117.2935, 39.4972]) => {
    onMounted(() => {
        map.value = new Map({
            layers: [],
            target: el,
            view: view.value,
            controls: defaultControls().extend([mousePositionControl]),
        });
        isMapReady.value = true
        titleLayer.value = initTdLayer(map.value)
        view.value.setCenter(center)
    });

    return {
        map,
        isMapReady
    }
}